/***********************************************************************************
 * 文件名： app.c
 * 版本�?1
 * 说明�?
 * 		APP逻辑实现，主要内容是响应各种事件�?
 * 修改记录�?
 * 	2021/04/28: 初版�?刘言�?
***********************************************************************************/
#include "a-app.h"
#include "a-comm.h"
#include "bsp-board.h"
#include "polsys.h"

#define _APP_OUT_MODE_SMOKE     0
#define _APP_OUT_MODE_WARM      1

NO_INIT static u8 App_FPUFlag; // 首次上电标记
NO_INIT static u8 App_mGear;   // 当前档位

static u8 App_mGearColor_R;
static u8 App_mGearColor_G;
static u8 App_mGearColor_B;
static u16 App_mGearValue;
static u8 App_mGearTime;

NO_INIT static bit App_mOuting; // 正在输出标志�?可以考虑用获取RHC状态来替代，节�?bit …�?
static bit App_mProtected;      // 短路保护状态中,避免按钮按住复位后反复输出反复闪灯。true：保护中，不可启�?
static bit App_mLocked;         // 已锁定（关机�?
// static bit App_mHasLoad;       // 输出模式已经切换过标志位。
static u8 App_mOutMode;         // 输出模式。 0 - 吸烟输出；1 - 预热输出。  

static u8 App_mTimeout; // 本次输出的超时时�?
static u8 App_mOutTime; // 输出计时�?00ms+1
static u8 App_mIdelTime;
extern u8 Comm_mErrorkind;
extern bit Comm_mErrorkindFlg;

static void UpdataGear();
static void StartTrigSmoke();
static void StopTrigSmoke();

// 以下事件函数看起来像中断，但是都在主程序态执行，可以执行耗时操作，但可能会拖慢整个软件的运行速度�?

// 软件启动事件。软件启动执行一次，函数名由 polsys 确定，不可任意修改。（看成是中断服务函数）
void App_Load()
{

    Board_Init();
    Pwm_Init();
    Adc_Init();
    RHC_Init();    // 电阻加热控制�?初始�?
    BMLite_Init(); // 电池管理初始�?
    Comm_Init();   // 通信功能初始�?

    if ((App_FPUFlag == 0x55) && (Board_ButtonIsDown() || App_mOuting))
    {

        CLEDC_SetColor(255, 0, 255);
        CLEDC_SetAction(CLEDC_ACT_FLASH, 3);
        App_mProtected = Board_ButtonIsDown()
#ifdef _APP_EN_MIC_SENSE
                         || Board_MicIsTrig()
#endif
            ;
    }
    else
    {
        CLEDC_SetColor(255, 255, 255);
        CLEDC_SetAction(CLEDC_ACT_ON, 200);
        App_mProtected = false;
        App_FPUFlag = 0x55;
    }
    App_mOuting = false;

    UpdataGear();

    Wdt_Init();
}

// 按钮有事件发生。函数名由组件确定，不可任意修改，无需声明。（看成是中断服务函数）
void Btn_Event(btn_ev_t e)
{
    App_mIdelTime = 0; // 任何按钮事件都清零空闲时�?
    if (!App_mLocked)
    {
        if (e == BTN_EV_DOWN)
        {
            StartTrigSmoke();
        }
        else if (e == BTN_EV_UP)
        {
            StopTrigSmoke();
        }
        else if (e == BTN_EV_CLICK_2)
        { // 开始预�?
            BMLite_SetRefreshStatus(false);
            RHC_SetTarget(_APP_WARM_VALUE);
            RHC_Start();
            App_mOuting = true;
            App_mTimeout = _APP_WARM_TIME;
            App_mOutMode = _APP_OUT_MODE_WARM;
            CLEDC_SetColor(0, 0, 0);
            CLEDC_SetAction(CLEDC_ACT_GRA_COLOR, 65535);
        }
        else if (e == BTN_EV_CLICK_3)
        {
            App_mGear++;
            UpdataGear();
            CLEDC_SetColor(App_mGearColor_R, App_mGearColor_G, App_mGearColor_B);
            CLEDC_SetAction(CLEDC_ACT_FLASH, 3);
        }
        else if (e == BTN_EV_CLICK_5)
        {
            App_mLocked = true;
            CLEDC_SetAction(CLEDC_ACT_ON, 20);
        }
    }
    else // 锁定了（关机�?
    {
        if (e == BTN_EV_CLICK_5)
        {
            App_mLocked = false;
            CLEDC_SetColor(App_mGearColor_R, App_mGearColor_G, App_mGearColor_B);
            CLEDC_SetAction(CLEDC_ACT_ON, 200);
        }
    }
}

#ifdef _APP_EN_MIC_SENSE
// SWSD （开关信号检�?咪头）事件。函数名由组件确定，不可任意修改，无需声明。（看成是中断服务函数）
void SWSD_Event(swsd_ev_t e)
{
    if (!App_mLocked)
    {
        if (e == SWSD_EV_TRIG) // 咪头触发，注意这个事件运行在中断�?
        {
            StartTrigSmoke();
        }
        else if (e == SWSD_EV_FREE)
        {
            StopTrigSmoke();
        }
    }
}
#endif

// RHC （电阻加热控制器）事件。函数名由组件确定，不可任意修改，无需声明。（看成是中断服务函数）
void RHC_Event(rhc_ev_t e)
{
    if (e & RHC_EV_SHORT_OUT)
    {
        App_mOuting = false;
        CLEDC_SetColor(255, 0, 255);
        CLEDC_SetAction(CLEDC_ACT_FLASH, 3);
    }
    else if (e & RHC_EV_NO_BATTERY)
    {
        App_mOuting = false;
        CLEDC_SetColor(255, 0, 0);
        CLEDC_SetAction(CLEDC_ACT_FLASH, 8);
    }
    else if (e & RHC_EV_NO_LOAD)
    {
            if(App_mOutMode == _APP_OUT_MODE_WARM)
            {
                RHC_SetWarmTarget(_APP_WARM_VALUE);//预热状态下，尾灯是关闭的所以补偿不需要太大
            }
            else
            {
                RHC_SetNoLoadTarget(App_mGearValue);
            }
    }
    else if (e & RHC_EV_LOADED)
    {
            if(App_mOutMode == _APP_OUT_MODE_WARM)
            {
                RHC_SetTarget(_APP_WARM_VALUE);
            }
            else
            {
                RHC_SetTarget(App_mGearValue);
            }
    }
}

// 电池事件。电池管理组件发来的事件通知
void BMLite_Event(bmlite_ev_t e)
{
    if (e == BMLITE_EV_DC_PULL_OUT)
    {
        CLEDC_SetAction(CLEDC_ACT_GRA_OFF, 0); // 渐灭
    }
    if (e == BMLITE_EV_CHARGE_FULL)
    {
        CLEDC_SetColor(0x00, 0xFF, 0x00);
        CLEDC_SetAction(CLEDC_ACT_ON, 65535); // 亮绿�?
    }
}

// 定时器事件。间�?00ms执行一�?
void App_Timer()
{
    if (App_mOuting)
    {
        App_mIdelTime = 0;
        App_mOutTime++;
        if (App_mOutTime >= App_mTimeout)
        { // 超时停止吸烟输出
            RHC_Stop();
            App_mOuting = false;
            CLEDC_SetColor(App_mGearColor_R, App_mGearColor_G, App_mGearColor_B);
            CLEDC_SetAction(CLEDC_ACT_FLASH, 6);
        }
    }
    else
    {
        App_mOutTime = 0;
        App_mIdelTime++;
        if (App_mIdelTime == 4)
        {
            BMLite_SetRefreshStatus(true); // 停止输出达到400ms了，开启电池刷新�?
        }
        // 停止输出后判断是否要亮充电指示灯
        if (CLEDC_GetAction() == CLEDC_ACT_NULL && (!Comm_IsRuning())) // LED空闲 且不在通信状�?
        {
            if (BMLite_DCConnected()) // 已连接充电器
            {
                if (BMLite_IsCharging())
                {
                    CLEDC_SetColor(0xff, 150, 0x00);
                    CLEDC_SetAction(CLEDC_ACT_BREATH, 65535); // 黄色呼吸
                }
                else
                {
                    CLEDC_SetColor(0x00, 0xFF, 0x00);
                    CLEDC_SetAction(CLEDC_ACT_ON, 65535); // 亮绿�?
                }
            }
            else // 未输出、LED空闲、未连接充电器，进入低功�?
            {
                if (App_mIdelTime >= 5)
                {
                    BMLite_SetRefreshStatus(false); // 休眠前停止电池状态刷新，用于唤醒后先进行通信，通信功能与充电识别会有冲突，不能同时开�?
                    Board_Sleep();
                    App_mIdelTime = 0;

                    if (!OVAL) // 不是端口唤醒，肯定不需要通信，所以恢复电池状态刷�?
                    {
                        BMLite_SetRefreshStatus(true);
                    }
                    else
                    {
                        Comm_Start(); // 尝试通信
                                      // 由通信功能模块 comm 控制何时结束通信模式以及恢复电池状态刷新�?
                    }
                }
            }
        }
    }
}

// 内部函数

// 更新档位参数
static void UpdataGear()
{
    if (App_mGear >= _APP_GEARS)
        App_mGear = 0;
    if (App_mGear == 0)
    {
        App_mGearValue = _APP_GEAR_1_VALUE;
        App_mGearColor_R = (u8)((_APP_GEAR_1_COLOR & 0x00FF0000) >> 16);
        App_mGearColor_G = (u8)((_APP_GEAR_1_COLOR & 0x0000FF00) >> 8);
        App_mGearColor_B = (u8)((_APP_GEAR_1_COLOR & 0x000000FF));
        App_mGearTime = _APP_GEAR_1_TIME;
    }
#if (_APP_GEARS >= 2)
    else if (App_mGear == 1)
    {
        App_mGearValue = _APP_GEAR_2_VALUE;
        App_mGearColor_R = (u8)((_APP_GEAR_2_COLOR & 0x00FF0000) >> 16);
        App_mGearColor_G = (u8)((_APP_GEAR_2_COLOR & 0x0000FF00) >> 8);
        App_mGearColor_B = (u8)((_APP_GEAR_2_COLOR & 0x000000FF));
        App_mGearTime = _APP_GEAR_2_TIME;
    }
#endif
#if (_APP_GEARS >= 3)
    else if (App_mGear == 2)
    {
        App_mGearValue = _APP_GEAR_3_VALUE;
        App_mGearColor_R = (u8)((_APP_GEAR_3_COLOR & 0x00FF0000) >> 16);
        App_mGearColor_G = (u8)((_APP_GEAR_3_COLOR & 0x0000FF00) >> 8);
        App_mGearColor_B = (u8)((_APP_GEAR_3_COLOR & 0x000000FF));
        App_mGearTime = _APP_GEAR_3_TIME;
    }
#endif
#if (_APP_GEARS >= 4)
    else if (App_mGear == 3)
    {
        App_mGearValue = _APP_GEAR_4_VALUE;
        App_mGearColor_R = (u8)((_APP_GEAR_4_COLOR & 0x00FF0000) >> 16);
        App_mGearColor_G = (u8)((_APP_GEAR_4_COLOR & 0x0000FF00) >> 8);
        App_mGearColor_B = (u8)((_APP_GEAR_4_COLOR & 0x000000FF));
        App_mGearTime = _APP_GEAR_4_TIME;
    }
#endif
}

// （按钮、咪头）触发的开始吸烟输�?
static void StartTrigSmoke()
{
    if (App_mProtected == false) // 未保护，可以启动
    {
        if (BMLite_NoBattery()) // 没电�?
        {
            CLEDC_SetColor(255, 0, 0);
            CLEDC_SetAction(CLEDC_ACT_FLASH, 8);
        }
        else // 有电
        {
            BMLite_SetRefreshStatus(false); // 暂停刷新电池状�?停止输出400ms后再启动电池状态刷�?
            // 默认认为带载了,按带载输出
            // App_mHasLoad = true;
            RHC_SetTarget(App_mGearValue);
            RHC_Start();
            App_mOuting = true;
            App_mTimeout = App_mGearTime;
            App_mOutTime = 0;
            App_mOutMode = _APP_OUT_MODE_SMOKE;
            CLEDC_SetColor(App_mGearColor_R, App_mGearColor_G, App_mGearColor_B);
            CLEDC_SetAction(CLEDC_ACT_GRA_ON, 65535);
        }
    }
}

// （按钮、咪头）触发的停止吸烟输�?
static void StopTrigSmoke()
{
    // 停止400ms后再启动电池状态刷�?
    RHC_Stop();
    App_mOuting = false;
    App_mProtected = false; // 标记下次可以启动
    if (CLEDC_GetAction() == CLEDC_ACT_GRA_ON)
    {
        CLEDC_SetAction(CLEDC_ACT_GRA_OFF, 0);
    }
}
